package com.fc.mall.portal.wechat;

import com.fc.mall.exception.ServiceException;
import com.fc.mall.portal.wechat.dto.WxConfig;
import com.fc.mall.util.Utils;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

@Slf4j
public class WxPay {

    private static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";

    private WxConfig wxConfig;

    public WxPay(WxConfig wxConfig) {
        this.wxConfig = wxConfig;
    }

    public Map<String, String> refund(String orderNo, String refundNo, int totalFee, int refundFee, String refundDesc) {
        try {
            SortedMap<String, String> parameters =
                    buildRefundParameters(wxConfig, orderNo, refundNo, totalFee, refundFee, refundDesc);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Invoke refund with [{}]", parameters);
            }
            String xmlStr = WxPaymentUtil.requestWithCert(wxConfig, REFUND_URL,
                    parameters, 8000, 10000);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Invoke refund return [{}]", xmlStr);
            }

            Map<String, String> result = WxPaymentUtil
                    .processResponse(WxPaymentUtil.xmlToMap(xmlStr), wxConfig.getPayKey());

            if ("FAIL".equals(result.get("return_code"))) {
                throw new ServiceException("微信退款失败");
            }

            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("退款失败");
        }
    }

    private SortedMap<String, String> buildRefundParameters(WxConfig wxConfig,
                                                            String orderNo,
                                                            String refundNo,
                                                            int totalFee,
                                                            int refundFee,
                                                            String refundDesc) {
        SortedMap<String, String> parameters = new TreeMap<>();

        parameters.put("appid", wxConfig.getAppId());
        parameters.put("mch_id", wxConfig.getMchId());
        parameters.put("nonce_str", Utils.generateId());
        parameters.put("notify_url", wxConfig.getNotifyUrl());
        parameters.put("out_refund_no", refundNo);
        parameters.put("out_trade_no", orderNo);
        parameters.put("refund_desc", refundDesc);
        parameters.put("refund_fee", String.valueOf(refundFee));

        if (wxConfig.isUseWsp()) {
            parameters.put("sub_appid", wxConfig.getSubAppId());
            parameters.put("sub_mch_id", wxConfig.getSubMchId());
        }

        parameters.put("total_fee", String.valueOf(totalFee));
        parameters.put("sign", WxPaymentUtil.generateSignature(parameters, wxConfig.getPayKey()));

        return parameters;
    }
}
